package de.upb.aquarium.api.light;

import java.util.Arrays;

import javax.media.opengl.GL;

import de.upb.aquarium.api.utility.VectorFloat;

public class SpotlightSource extends PointLightSource {

	private VectorFloat direction;

	private float spotCutoff;
	private float spotExponent;
	
	public SpotlightSource(		
			VectorFloat position,
			VectorFloat direction,
			float attenuationConst,
			float attenuationLinear,
			float attenuationQuadratic,
			float spotExponent,
			float spotCutoff,
			VectorFloat colorAmbient,
			VectorFloat colorDiffuse,
			VectorFloat colorSpecular) {
		
		super(position,
			  attenuationConst,
			  attenuationLinear,
			  attenuationQuadratic,
			  colorAmbient,
			  colorDiffuse,
			  colorSpecular
			 );
		
		setDirection(direction);
		setSpotCutoff(spotCutoff);
		setSpotExponent(spotExponent);
	}

	@Override
	public void enable(GL gl, int lightIdentifier) {
		super.enable(gl, lightIdentifier);
		
		float[] dir = Arrays.copyOf(direction.data, 4);
		gl.glLightfv(lightIdentifier, GL.GL_SPOT_DIRECTION, dir, 0);
		gl.glLightf(lightIdentifier, GL.GL_SPOT_EXPONENT, spotExponent);
		gl.glLightf(lightIdentifier, GL.GL_SPOT_CUTOFF, spotCutoff);
	}

	public float getSpotCutoff() {
		return spotCutoff;
	}

	public void setSpotCutoff(float spotCutoff) {
		if (((spotCutoff < 0.0f) || (spotCutoff > 90.0f)) && (spotCutoff != 180.0f))
		{
			throw new IllegalArgumentException("Spot cutoff must be in [0.0,90.0]" +
					"or exactly 180.0f. Given value was " + spotCutoff + ".");
		}
		
		this.spotCutoff = spotCutoff;
	}

	public float getSpotExponent() {
		return spotExponent;
	}

	public void setSpotExponent(float spotExponent) {
		if ((spotExponent < 0.0f) || (spotExponent > 128.0f))
		{
			throw new IllegalArgumentException("Spot exponent must be in " +
					"the interval [0,128]. Given value was " + spotExponent +
					".");
		}
		
		this.spotExponent = spotExponent;
	}

	@Override
	public void disable() {
		// nothing to do.

	}
		
	public VectorFloat getDirection() {
		
		return direction;
	}

	public void setDirection(VectorFloat direction) {
		
		if (direction.getSize() != 3)
		{
			throw new IllegalArgumentException("Direction of a light source " +
					"must have exactly 3 coordinates.");
		}
		this.direction = direction;
	}

}
